package com.chipcoo.shiro.authz;

import org.apache.shiro.authz.Permission;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Set;

/**
 *  规则
 *    +资源字符串+权限位+实例ID
 *
 *  以+开头 中间通过+分割
 *
 *  权限CURD：
 *     0 表示所有权限
 *     1 C CREATE 0001
 *     2 U UPDATE 0010
 *     4 R READ 0100
 *     8 D DELETE 1000
 *
 *  如 +user+10 表示对资源user拥有修改/查看权限
 *
 *  不考虑一些异常情况
 *
 */
public class BitPermission implements Permission {
    private static final String WILDCARD_TOKEN = "*";
    private static final String PART_DIVIDER_TOKEN = ":";
    private static final String SUBPART_DIVIDER_TOKEN = ",";

    private String resourceIdentify;
    private int permissionBit;
    private Set<String> instanceSet;

    /**
     * 资源字符串:权限位:实例ID；以+开头中间通过+分割；
     * 权限：0 表示所有权限；1 新增（二进制：0001）、2 修改（二进制：0010）、4 删除（二进制：0100）、8 查看（二进制：1000）；
     * 如user:10 表示对资源user拥有修改/查看权限。
     * @param permissionString
     */
    public BitPermission(String permissionString) {
        if ( null == permissionString || !permissionString.trim().startsWith("+") ) {
            throw new IllegalArgumentException("Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.");
        }
        permissionString = permissionString.trim().substring(1);

        String[] array = permissionString.split(PART_DIVIDER_TOKEN);

        if (array.length > 0) resourceIdentify = array[0];
        if (StringUtils.isEmpty(resourceIdentify)) resourceIdentify = WILDCARD_TOKEN;


        if (array.length > 1)  permissionBit = Integer.valueOf(array[1]);

        if (array.length > 2) {
            if(!StringUtils.isEmpty(array[2])){
                instanceSet = CollectionUtils.asSet(array[2].split(SUBPART_DIVIDER_TOKEN));
            }
        }
    }

    @Override
    public boolean implies(Permission p) {
        if(!(p instanceof  BitPermission)) return false;

        BitPermission required = (BitPermission) p;

        if( !( WILDCARD_TOKEN.equals(this.resourceIdentify) || this.resourceIdentify.equals(required.resourceIdentify) ) ) {
            return false;
        }

        if( !(this.permissionBit ==0 || (this.permissionBit & required.permissionBit) != 0)) {
            return false;
        }


        if(null!=this.instanceSet) {
            //如果空或者没有 这假设拥有所有资源的
            if (!this.instanceSet.contains(WILDCARD_TOKEN)) {
                //要求指定资源&没有指定资源
                if (null != required.instanceSet && !this.instanceSet.containsAll(required.instanceSet))
                    return false;
            }
        }





        return true;
    }
}